﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Daphne.GameShared;

namespace GameEngine.MoveGenerators
{
    public class BaseKingMoveGenerator: BaseMoveGenerator, IKingMoveGenerator
    {
        /// <summary>
        /// Abstract virtual method for returning moves in one direction
        /// </summary>
        protected virtual List<Position> GetKingStepsInDiagonal(Position figurePos, enumDiagonalDir dir)
        {
            return new List<Position>();
        }

        /// <summary>
        /// Returns all king moves
        /// </summary>
        public List<Position> GetKingMoves(Position figure)
        {
            List<Position> list = new List<Position>();

            list.AddRange(GetKingStepsInDiagonal(figure, enumDiagonalDir.NorthEast));
            list.AddRange(GetKingStepsInDiagonal(figure, enumDiagonalDir.NorthWest));
            list.AddRange(GetKingStepsInDiagonal(figure, enumDiagonalDir.SouthEast));
            list.AddRange(GetKingStepsInDiagonal(figure, enumDiagonalDir.SouthWest));

            return list;
        }

        /// <summary>
        /// Abstract virtual method for getting jumps in specific direction
        /// </summary>
        protected virtual List<Position> CheckKingJumpsInDirection(Position pos, enumDiagonalDir dir, enumFigureColor clrMovedFigure)
        {
            return new List<Position>();
        }


        /// <summary>
        /// Evaluates king jumps in all directions
        /// </summary>
        /// <param name="figurePos">king position</param>
        /// <param name="clrMovedFigure">kings color - for investigating multiple jumps for long-range kings</param>
        /// <param name="ignoredDirection">direction to ignore for multiple jump - long range kings cannot jump back</param>
        /// <returns>list of possible positions</returns>
        protected List<Position> EvaluateKingJumps(Position figurePos, enumFigureColor clrMovedFigure, enumDiagonalDir? ignoredDirection = null)
        {
            List<Position> list = new List<Position>();
            Position destField = Position.Empty;
            if (ignoredDirection != enumDiagonalDir.NorthWest)
                list.AddRange(CheckKingJumpsInDirection(figurePos, enumDiagonalDir.NorthWest, clrMovedFigure));
            if (ignoredDirection != enumDiagonalDir.NorthEast)
                list.AddRange(CheckKingJumpsInDirection(figurePos, enumDiagonalDir.NorthEast, clrMovedFigure));
            if (ignoredDirection != enumDiagonalDir.SouthWest)
                list.AddRange(CheckKingJumpsInDirection(figurePos, enumDiagonalDir.SouthWest, clrMovedFigure));
            if (ignoredDirection != enumDiagonalDir.SouthEast)
                list.AddRange(CheckKingJumpsInDirection(figurePos, enumDiagonalDir.SouthEast, clrMovedFigure));

            return list;
        }


        /// <summary>
        /// Global method for generating king jumps
        /// </summary>
        public List<Position> GetKingJumps(Position figurePos)
        {
            enumFigureColor clrMovedFigure = GameBoard.GetField(figurePos.Row, figurePos.Col).FigureColor();
            return EvaluateKingJumps(figurePos, clrMovedFigure);
        }

        /// <summary>
        /// Returns king jumps for specific figure with ignored direction, used to investigate multiple jump
        /// </summary>
        /// <param name="figure">Figure position</param>
        /// <param name="ignoredDirection">Ignored direction to look for jump</param>
        /// <returns></returns>
        public List<Position> GetKingJumps(Position figure, enumDiagonalDir? ignoredDirection)
        {
            enumFigureType figureType = GameBoard.GetField(figure);
            return EvaluateKingJumps(figure, figureType.FigureColor(), ignoredDirection);
        }

    }
}
